Self crossing

Time: O(N); Space: O(1); hard

You are given an array x of n positive numbers.

You: * start at point (0,0) and * moves x[0] metres to the North, then * x[1] metres to the West, * x[2] metres to the South, * x[3] metres to the East and so on.

In other words, after each move your direction changes counter-clockwise.

Write a one-pass algorithm with O(1) extra space to determine, if your path crosses itself, or not.

Example 1:

Self crossing

+---+
|   |
+---+----->
    |

Input: x = [2, 1, 1, 2],

Output: True

Example 2:

Not self crossing

+------+
|      |
|
|
+------------->

Input: x = [1, 2, 3, 4]

Output: Fallse

Example 3:

Self crossing

+------+
|      |
+------+---->

Input: x = [1, 1, 1, 1]

Output: True

[1]:
class Solution1(object):
    def isSelfCrossing(self, x) -> bool:
        """
        :type x: List[int]
        :rtype: bool
        """
        if len(x) >= 5 and \
           x[3] == x[1] and \
           x[4] + x[0] >= x[2]:
            # Crossing in a loop
            return True

        for i in range(3, len(x)):
            if x[i] >= x[i - 2] and \
               x[i - 3] >= x[i - 1]:
                # Case 2: current line crosses the line 4 steps ahead of it
                #         Fourth line crosses first line and onward
                return True
            elif i >= 5 and x[i - 4] <= x[i - 2] and \
                            x[i] + x[i - 4] >= x[i - 2] and \
                            x[i - 1] <= x[i - 3] and \
                            x[i - 5] + x[i - 1] >= x[i - 3]:
                # Case 3: current line crosses the line 6 steps ahead of it
                #         Sixth line crosses first line and onward
                return True
        return False

[2]:
s = Solution1()
x = [2, 1, 1, 2]
assert s.isSelfCrossing(x) == True
x = [1, 2, 3, 4]
assert s.isSelfCrossing(x) == False
x = [1, 1, 1, 1]
assert s.isSelfCrossing(x) == True